#include "GlobalDefines.h"
#include "Geometry.h"
#include "Partition.h"
#include "Excitation.h"
#include "Solver.h"
#include "Result.h"
#include "omp.h"
#include <climits>
#include <ctime>

int main()
{
	const int N =6;
	clock_t start,finish;
	start = clock();
	MoM_Geometry* Geo = new MoM_Geometry();
	Geo->ReadGeometry("cube.dat",5);
	PlaneWave* Ex = new PlaneWave(C, 0, 0, 0);
	MoM_Partition* Part[N];
	//sphere
// 	Part[0] = new MoM_Partition(Geo,Ex,0,DBL_MAX,0,DBL_MAX,0,DBL_MAX);
// 	Part[1] = new MoM_Partition(Geo,Ex,0,DBL_MAX,-DBL_MAX,0,0,DBL_MAX);
// 	Part[2] = new MoM_Partition(Geo,Ex,-DBL_MAX,0,-DBL_MAX,0,0,DBL_MAX);
// 	Part[3] = new MoM_Partition(Geo,Ex,-DBL_MAX,0,0,DBL_MAX,0,DBL_MAX);
// 	Part[4] = new MoM_Partition(Geo,Ex,0,DBL_MAX,0,DBL_MAX,-DBL_MAX,0);
// 	Part[5] = new MoM_Partition(Geo,Ex,0,DBL_MAX,-DBL_MAX,0,-DBL_MAX,0);
// 	Part[6] = new MoM_Partition(Geo,Ex,-DBL_MAX,0,-DBL_MAX,0,-DBL_MAX,0);
// 	Part[7] = new MoM_Partition(Geo,Ex,-DBL_MAX,0,0,DBL_MAX,-DBL_MAX,0);
// 	Part[0] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,0,DBL_MAX,0,DBL_MAX);
// 	Part[1] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,-DBL_MAX,0,0,DBL_MAX);
// 	Part[2] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,-DBL_MAX,0,-DBL_MAX,0);
// 	Part[3] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,0,DBL_MAX,-DBL_MAX,0);
// 	Part[0] = new MoM_Partition(Geo,Ex,0,DBL_MAX,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX);
// 	Part[1] = new MoM_Partition(Geo,Ex,-DBL_MAX,0,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX);
// 	Part[0] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX);

	//plate
// 	Part[0] = new MoM_Partition(Geo,Ex,-DBL_MAX,-0.5,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX);
// 	Part[1] = new MoM_Partition(Geo,Ex,-0.5,0.5,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX);
// 	Part[2] = new MoM_Partition(Geo,Ex,0.5,DBL_MAX,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX);

	//cube
	Part[0] = new MoM_Partition(Geo,Ex,-DBL_MAX,-0.5,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX);
	Part[1] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,-DBL_MAX,-0.5,-DBL_MAX,DBL_MAX);
	Part[2] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX,-DBL_MAX,-0.5);
	Part[3] = new MoM_Partition(Geo,Ex,0.5,DBL_MAX,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX);
	Part[4] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,0.5,DBL_MAX,-DBL_MAX,DBL_MAX);
	Part[5] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX,0.5,DBL_MAX);
// 	Part[0] = new MoM_Partition(Geo,Ex,-DBL_MAX,-0.4999,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX);
// 	Part[2] = new MoM_Partition(Geo,Ex,-0.4999,0.4999,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX);
// 	Part[1] = new MoM_Partition(Geo,Ex,0.4999,DBL_MAX,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX);

	//ecllipse
// 	Part[0] = new MoM_Partition(Geo,Ex,0,DBL_MAX,0,DBL_MAX,-DBL_MAX,DBL_MAX);
// 	Part[1] = new MoM_Partition(Geo,Ex,-DBL_MAX,0,0,DBL_MAX,-DBL_MAX,DBL_MAX);
// 	Part[2] = new MoM_Partition(Geo,Ex,-DBL_MAX,0,-DBL_MAX,0,-DBL_MAX,DBL_MAX);
// 	Part[3] = new MoM_Partition(Geo,Ex,0,DBL_MAX,-DBL_MAX,0,-DBL_MAX,DBL_MAX);
// 	Part[0] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,-DBL_MAX,0,-DBL_MAX,DBL_MAX);
// 	Part[1] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,0,DBL_MAX,-DBL_MAX,DBL_MAX);

	//corner
// 	Part[0] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,-DBL_MAX,0,-DBL_MAX,DBL_MAX);
// 	Part[1] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,0,DBL_MAX,-DBL_MAX,DBL_MAX);

	//cone
// 	Part[0] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX,-DBL_MAX,0);
// 	Part[1] = new MoM_Partition(Geo,Ex,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX,0.0001,DBL_MAX);

	//cylinder
// 	Part[0] = new MoM_Partition(Geo,Ex,-DBL_MAX,0,-DBL_MAX,0,-DBL_MAX,DBL_MAX);
// 	Part[1] = new MoM_Partition(Geo,Ex,-DBL_MAX,0,0,DBL_MAX,-DBL_MAX,DBL_MAX);
// 	Part[2] = new MoM_Partition(Geo,Ex,0,DBL_MAX,0,DBL_MAX,-DBL_MAX,DBL_MAX);
// 	Part[3] = new MoM_Partition(Geo,Ex,0,DBL_MAX,-DBL_MAX,0,-DBL_MAX,DBL_MAX);
	//2_sphere
// 	Part[0] = new MoM_Partition(Geo,Ex,-DBL_MAX,0,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX);
// 	Part[1] = new MoM_Partition(Geo,Ex,0,DBL_MAX,-DBL_MAX,DBL_MAX,-DBL_MAX,DBL_MAX);
	MoM_Solver* solver[N];
// #pragma omp parallel for num_threads(N)
	for (int i=0; i<N; i++)
	{
		solver[i] = new MoM_Solver(Part[i]);
	}
	real_data eps;
	for (int i=0; i<3; i++)
	{
		if (0 == i) eps=0.1;
		else if (1==i) eps=0.01;
		else eps=0.001;
// 		eps = 0.001;
// #pragma omp parallel for num_threads(N)
		for (int j=0; j<N; j++)
		{
			solver[j]->Execution(eps);
		}
	}

	RCS* result = new RCS(Geo,Ex,0,180,181,0,0,1,0);
	result->GetResults();
	finish = clock();
	std::cout<<"Total time:"<<real_data(finish - start)/CLOCKS_PER_SEC<<std::endl;
	return 0;
}